# -*- coding:utf-8 -*-
# @Time  : 2019/12/3 18:55
# @Author: wangxb
'''
# 根据本地指定路径下的apk进行解析微信ID
## 1、使用unzip解压jar包，解压.class文件到指定目录
## 2、使用jad反编译指定目录下的.class文件
'''
import datetime
import os
import subprocess
import time

from classes.jarOperation import generateJarFile, getAllClassesFileInAPK, changeFileSuffix, copyAPKToZip
from classes.searchContent import examineDirectory, FindConetent, traverseDocument

# apk包名
# apk_name = 'com.tencent.mm.apk'
# 不需要解析的app数组
appList = ["奇热漫画", "大角虫漫画", "樊登读书", "网易漫画", "酷听听书", "翻阅小说", "ONE·一个", "当当云阅读", "免费小说全集", "漫漫漫画", "潇湘书院小说阅读", "新漫画",
           "触漫", "咚漫", "鲸鱼阅读软件"]
# 项目的根路径
root_path = os.path.dirname(os.getcwd())
# apk文件路径
apk_file_path = root_path + os.sep + 'APKSources' + os.sep
# apk的zip文件路径
# apk_zip_file_path = ''
# 反编译后的zip文件路径
jar_zip_file_path = root_path + os.sep + 'zipSources'
# lanchon_tools工具所在路径
lanchon_tools_path = root_path + os.sep + 'dex-tools-lanchon'
# 搜索文件的根路径
classRootPath = root_path + os.sep + 'zipSources' + os.sep + 'classCatalog'
javaRootPath = root_path + os.sep + 'zipSources' + os.sep + 'javaCatalog'
# 搜索结果输出路径
outputPath = root_path + os.sep + 'output_files_jad.txt'


def totalProcess(apk_file_path):
    # apk的zip文件路径
    # apk_zip_file_path = changeFileSuffix(apk_file_path)
    apk_zip_file_path = 'D:\Work\Python\GetWeChatID\APKSources\com.youku.phone_9.3.0_241.zip'
    try:
        # 获取对应apk的zip包
        copyAPKToZip(apk_file_path, apk_zip_file_path)
        # 获取APK对应zip包中的classes.dex文件
        classes_list = getAllClassesFileInAPK(apk_zip_file_path)

        for classes_file in classes_list:
            try:
                print(
                    '\n#############################清理搜索目录#############################')
                # 删除之前搜索目录中遗留的文件
                examineDirectory(classRootPath)
                examineDirectory(javaRootPath)

                print(
                    '\n#############################Start decompile ' + classes_file + '#############################')
                # 生成classes.dex对应的jar包文件
                generateJarFile(apk_zip_file_path, lanchon_tools_path, classes_file)

                # 调用unzip解压jar包到目录 searchRootPath
                print("#######################开始 unzip解压jar包######################")
                # os.system(
                #     lanchon_tools_path[
                #     0:1] + ": && cd " + lanchon_tools_path + " && unzip classes-dex2jar.jar -d %s" % classRootPath)
                p = subprocess.Popen(lanchon_tools_path[
                                     0:1] + ": && cd " + lanchon_tools_path + " && unzip -o classes-dex2jar.jar -d %s" % classRootPath,
                                     shell=True)
                                     # shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                # # stdOutput, errOutput = p.communicate()
                # # print(stdOutput)
                # # print(errOutput)
                result = p.wait()
                if result != 0:
                    print("####################### unzip解压jar包出错 #######################")
                time.sleep(1)

                # 调用jad反编译 classRootPath 下的class文件
                print("#######################开始 jad反编译搜索目录下的.class文件######################")
                # os.system(
                #     lanchon_tools_path[
                #     0:1] + ": && cd " + lanchon_tools_path + " && jad.exe -r -ff -d %s -s Java %s/**/*.class " % (
                #         javaRootPath, classRootPath))
                # jad.exe -r -ff -d %s -s Java %s/**/*.class
                # 其中-r 表示恢复源文件的目录结构,，-ff 表示将类属性定义放在类方法定义之前， -d 表示输出目录，-s 表示文件的扩展名。所有的java文件将会被放置到src目录下。
                p = subprocess.Popen(lanchon_tools_path[
                                     0:1] + ": && cd " + lanchon_tools_path + " && jad.exe -o -8 -r -ff -d %s -s Java %s/**/*.class " % (
                                         javaRootPath, classRootPath), shell=True)
                                         # javaRootPath, classRootPath), shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE)

                # stdOutput, errOutput = p.communicate()
                # print(stdOutput)
                # print(errOutput)
                # p.wait()
                result = p.wait()
                if result != 0:
                    print("####################### jad反编译.class文件出错 #######################")
                time.sleep(1)

                # 根据关键字搜索指定路径下所有文件的内容
                findObj = FindConetent(javaRootPath)
                findObj.find_file(findObj)
                findObj.walk(findObj, outputPath, apk_file_path)

                # 删除之前搜索目录中遗留的文件
                examineDirectory(classRootPath)
                examineDirectory(javaRootPath)

            except Exception as e:
                print(e)

    except BaseException as errors:
        print(errors)
    finally:
        # 删除对应apk的zip包
        os.remove(apk_zip_file_path)


if __name__ == '__main__':

    start = datetime.datetime.now()
    # 获取本地制定路径下所有apk对象
    apkNameList = traverseDocument(apk_file_path)

    # 对数组中的apk进行解析
    for pkgName in apkNameList:

        try:
            # 在输出文件中区分每个app的微信ID
            f = open(outputPath, "a", encoding='utf-8')
            f.write('\n#############################Start An APP : %s ##################################\n' % pkgName)
            f.close()
            apk_file_path_final = apk_file_path + pkgName
            # 获取apk后，进行后续的dex2jar和jd-gui，以及search
            totalProcess(apk_file_path_final)
            f = open(outputPath, "a", encoding='utf-8')
            f.write('#############################End An APP : %s ##################################\n'% pkgName)
            f.close()
        except BaseException as error:
            print(error)
        # finally:
        #     f.close()
    end = datetime.datetime.now()
    print('Running time: %s Seconds' % (end - start))
